package cn.tedu.aop.demo;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

/**
 * 定义一个切面，用于在计算器类的方法中动态插入逻辑
 * 在Spring中一个切面类需要:
 * 1:添加@Component注解   首先必须被Spring管理
 * 2:添加@Aspect注解      用于标识它是一个切面类
 */
@Component
@Aspect
public class SysoutAspect {
    /**
     * @Before注解用于标注该方法是在实际方法调用前切入并执行
     * 该注解中要传入一个参数，用于定义切入点(目标方法,target)，就是实际调用的方法签名
     *
     * 切入点描述:
     * execution(方法签名)
     *
     * 方法签名格式示例:
     * public int cn.tedu.aop.demo.CalculatorImpl.add(..)
     * 修饰符 返回值类型 类完全限定名.方法名(参数列表)
     * 其中参数列表通常可以使用".."标识任意参数
     *
     * 方法名可以使用"*",标识该类的任意方法:
     * public int cn.tedu.aop.demo.CalculatorImpl.*(..)
     *
     *
     * 方法中可以接收一个参数:JoinPoint 切入点
     * 该对象描述了当前切面切入的实际方法描述信息。
     */
//    @Before("execution(public int cn.tedu.aop.demo.CalculatorImpl.add(int,int))")
//    @Before("execution(public int cn.tedu.aop.demo.CalculatorImpl.add(int,double))")//切入点描述有误则无效
//    @Before("execution(public double cn.tedu.aop.demo.CalculatorImpl.add(double,double))")
//   @Before("execution(public java.lang.String cn.tedu.aop.demo.CalculatorImpl.add(java.lang.String,java.lang.String))")//如果参数或返回值为引用类型，也要使用完全限定名:包名.类名
//   @Before("execution(public int cn.tedu.aop.demo.CalculatorImpl.add(..))")//参数类型任意，但是仍然只有int add(int,int)被切入，原因是其他add方法返回值类型也不同
//    @Before("execution(public * cn.tedu.aop.demo.CalculatorImpl.add(..))")//返回值类型可以使用"*"表示任意类型的返回值均可
    @Before("execution(public * cn.tedu.aop.demo.CalculatorImpl.*(..))")
  public void before(JoinPoint point){
            System.out.println("切面类在方法调用前被调用！！！");
            System.out.println(point);

  }

}
